from django.http import Http404
from rest_framework.exceptions import PermissionDenied, AuthenticationFailed, NotAuthenticated, ValidationError
from rest_framework.views import set_rollback

from database.models import SystemWrong
from utils.config.App import OPEN_MIDDLE_SYSTEM_ERROR_RECORD
from utils.unite.errors import ServiceUnavailable
from utils.unite.result import ApiResponse, get_serializer_error


# rest_framework.views.exception_handler
def custom_exception_handler(exc, context):
    """
    自定义异常处理类
    :param exc:
    :param context:
    :return:
    """
    if OPEN_MIDDLE_SYSTEM_ERROR_RECORD:
        request = context['request']
        SystemWrong.objects.create(path=request._request.path,
                                   error=exc.detail,
                                   error_code=exc.status_code)
    if isinstance(exc, ServiceUnavailable):
        set_rollback()
        return ApiResponse(code=exc.status_code, message=exc.detail)

    elif isinstance(exc, Http404):
        msg = u'对象未找到.'
        # msg = 'Not found.'
        data = {'detail': msg}

        set_rollback()
        return ApiResponse(code=404, data=data, message=msg)

    elif isinstance(exc, PermissionDenied):
        msg = u'您没有对应的权限.'
        # msg = 'Permission denied.'
        data = {
            'detail': msg
        }
        exc_message = str(exc)
        if 'CSRF' in exc_message:
            data['detail'] = exc_message

        set_rollback()
        return ApiResponse(code=403, data=data, message=msg)

    elif isinstance(exc, AuthenticationFailed):
        msg = u'登录超时,请重新登录.'
        # msg = 'Token has expired.'
        data = {
            'detail': msg
        }
        exc_message = str(exc)
        if 'CSRF' in exc_message:
            data['detail'] = exc_message

        set_rollback()
        return ApiResponse(code=401, data=data, message=msg)

    elif isinstance(exc, NotAuthenticated):
        msg = u'登录超时,请重新登录.'
        # msg = 'Token has expired.'
        data = {
            'detail': msg
        }
        exc_message = str(exc)
        if 'CSRF' in exc_message:
            data['detail'] = exc_message

        set_rollback()
        return ApiResponse(code=401, data=data, message=msg)

    elif isinstance(exc, ValidationError):
        msg = u'验证失败.'
        data = {
            'detail': msg
        }

        data['detail'] = get_serializer_error(exc.detail)
        set_rollback()
        return ApiResponse(code=401, data=data, message=msg)

    else:
        # msg = 'System error, please try again.'
        msg = '系统错误,请之后重新尝试或者联系管理员.'
        data = {
            'detail': msg
        }
        exc_message = str(exc)
        data['detail'] = exc_message
        set_rollback()
        return ApiResponse(code=203, data=data, message=msg)
